package controllers

import (
	"image"
	"github.com/fogleman/gg"
	"github.com/nfnt/resize"
	"Pandaria/services/wechatService"
	"github.com/astaxie/beego/logs"
	"github.com/astaxie/beego/orm"
	"Pandaria/models"
	"fmt"
	"log"
	"image/png"
	"net/http"
	"github.com/golang/freetype/truetype"
	"io/ioutil"
	"golang.org/x/image/font"
	cutter "Pandaria/services/imageCutter"
)

type UserController struct {
	BaseController
}

func (this *UserController) Get() {
	momentId, err := this.GetInt("momentId")
	logs.Debug("momentID", momentId)

	o := orm.NewOrm()
	orm.Debug = true
	o.Using("default")

	moment := models.Moment{Id: momentId}
	e := o.Read(&moment)
	if e == orm.ErrNoRows {
		this.OutputImgNotFound("moment查询不到")
		return
	} else if err == orm.ErrMissPK {
		this.OutputImgNotFound("moment找不到主键")
		return
	}

	userIdInt32 := int32(moment.UserId)
	user := models.User{Id: moment.UserId}
	e = o.Read(&user)
	if e == orm.ErrNoRows {
		this.OutputImgNotFound("user查询不到")
		return
	} else if err == orm.ErrMissPK {
		this.OutputImgNotFound("user找不到主键")
		return
	}

	tempQrcode := true
	if user.Qr_code_type == 1 {
		tempQrcode = false
	}
	logs.Debug(moment.Img_content)
	qrcode, err := wechatService.GetUserQRCode(userIdInt32, tempQrcode)
	if err != nil {
		logs.Error(err)
		this.OutputImgNotFound(err.Error())
		return
	}

	momentImage, err := getImageByUrl(moment.Img_content)
	this.OutputImg(generateUserQrCodeImage(qrcode, momentImage, moment.Content, user.Wx_nickname, userIdInt32), "jpg")
	return

}

func getImageByUrl(url string) (img image.Image, err error) {
	defaultImagePath := "static/img/moment_default.jpg"
	if url != "" {

		res, err := http.Get(url)
		if err != nil {
			fmt.Println("get image url error: " + err.Error())
			return nil, err
		}
		if res == nil {
			img, err = gg.LoadImage(defaultImagePath)
			if err != nil {

				log.Fatal(err)
			}
		}
		if res.StatusCode != 200 {
			img, err = gg.LoadImage(defaultImagePath)
			if err != nil {
				log.Fatal(err)
			}
		}

		defer res.Body.Close()

		img, _, err = image.Decode(res.Body)
		if err != nil {
			log.Fatal(err)
			img, err = png.Decode(res.Body)
			if err != nil {
				log.Fatal(err)
			}
		}

	} else {
		img, err = gg.LoadImage(defaultImagePath)
		if err != nil {
			log.Fatal(err)
		}
	}

	return
}

func generateUserQrCodeImage(qrCodeImage image.Image, momentImage image.Image, momentWord string, userName string, userId int32) (mixedImage image.Image) {

	var momentSizeW float64 = 600
	var momentSizeH float64 = 600
	var momentPointX int = 75
	var momentPointY int = 225

	var qrCodeSize float64 = 150
	var qrCodePointX int = 298
	var qrCodePointY int = 1087

	var boldFontFile string = "static/fonts/PingFang-SC-Bold.ttf"

	var momentWordsSize float64 = 30
	var momentWordPointX float64 = 67
	var momentWordPointY float64 = 960

	var userNameSize float64 = 30
	var userNamePoinxX float64 = 530
	var userNamePoinxY float64 = 1045

	boldFont, err := LoadFont(boldFontFile)
	if err != nil {
		logs.Error(err)
	}

	backgroundImage, err := gg.LoadImage("static/img/background.jpg")
	if err != nil {
		logs.Error(err)
	}

	//缩放为合适大小
	qrcode := resize.Resize(uint(qrCodeSize), uint(qrCodeSize), qrCodeImage, resize.Lanczos3)

	momentImageSize := momentImage.Bounds().Size()

	if momentImageSize.X <= momentImageSize.Y {
		//宽小于高
		momentImage = resize.Resize(uint(momentSizeW),
			uint(int(momentSizeW) * momentImageSize.Y / momentImageSize.X),
			momentImage, resize.Lanczos3)
	}else {
		//宽大于高
		momentImage = resize.Resize(uint(int(momentSizeH) * momentImageSize.X/momentImageSize.Y),
			uint(momentSizeH),
			momentImage, resize.Lanczos3)
	}

	moment, err := cutter.Crop(momentImage,
		cutter.Config{Width: int(momentSizeW), Height: int(600), Mode: cutter.Centered,Options: cutter.Copy})
	if err != nil {
		logs.Error(err)
	}

	//创建画布-已背景图片为底
	canvas := gg.NewContextForImage(backgroundImage)

	canvas.DrawRectangle(float64(momentPointX), float64(momentPointY), momentSizeW, momentSizeH)
	canvas.Clip()
	canvas.DrawImage(moment, momentPointX, momentPointY)
	canvas.Fill()

	canvas.ResetClip() //重置剪切

	canvas.DrawRectangle(float64(qrCodePointX), float64(qrCodePointY), qrCodeSize, qrCodeSize)
	canvas.Clip()
	canvas.DrawImage(qrcode, qrCodePointX, qrCodePointY)
	canvas.Fill()

	canvas.ResetClip()

	if momentWord == "" {
		momentWord = "打卡"
	}
	text1 := ""
	text2 := ""
	stringList := SplitStringIntoLines(momentWord, 20)
	if len(stringList) > 1 {
		text1 = string([]rune(stringList[0]))
		text2 = string([]rune(stringList[1])) + "..."
	} else {
		text1 = stringList[0]
	}

	canvas.SetFontFace(GetFontFace(boldFont, momentWordsSize))
	canvas.SetRGBA255(255, 255, 255, 255)
	canvas.DrawString(text1, momentWordPointX, momentWordPointY)
	if (text2 != "") {
		canvas.DrawString(text2, momentWordPointX, momentWordPointY+40)
	}

	userName = "---" + userName
	canvas.SetFontFace(GetFontFace(boldFont, userNameSize))
	canvas.SetRGBA255(255, 255, 255, 255)
	canvas.DrawString(userName, userNamePoinxX, userNamePoinxY)
	canvas.Fill()

	return canvas.Image()
}

func SplitStringIntoLines(raw string, lineSize int) []string {
	var stringList []string
	rs := []rune(raw)
	length := len(rs)
	for offset := 0; offset < length; offset += lineSize {
		end := offset + lineSize
		if end > length {
			end = length
		}
		slice := rs[offset: end]
		stringList = append(stringList, string(slice))
	}
	return stringList
}

func LoadFont(path string) (f *truetype.Font, err error) {
	fontBytes, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, err
	}
	f, err = truetype.Parse(fontBytes)
	if err != nil {
		return nil, err
	}
	return
}
func GetFontFace(f *truetype.Font, points float64) (font.Face) {
	face := truetype.NewFace(f, &truetype.Options{
		Size: points,
		// Hinting: font.HintingFull,
	})
	return face
}
